<?php

/**
 *
 * Class TaskController
 * @date 2022-05
 */

namespace app\admin\controller;


use app\common\model\GiftModel;
use app\common\model\PropsNewModel;
use app\common\model\TaskModel;
use app\common\model\TaskRewardModel;
use app\common\model\UserTaskModel;
use think\Db;
use think\db\Query;
use think\facade\Request;
use think\Validate;

class TaskController extends BaseController
{

    /**
     * 任务列表
     * @return mixed
     */
    public function index()
    {
        $type_cate = TaskModel::TYPE_CATE;
        $this->assign("type_cate", $type_cate);
        return $this->fetch();
    }

    /**
     * 列表数据
     * @return \think\response\Json
     */
    public function getlist()
    {
        $model = TaskModel::with(['reward', 'admin' => function (Query $query) {
            $query->field('id,name');
        }]);

        if (in_array($type = $this->get('type'), ['0', 1, 2, 3])) {
            $model = $model->where('type', $type);
        }

        if (in_array($status = $this->get('status'), ['0', 1])) {
            $model = $model->where('status', $status);
        }

        if ($name = trim($this->get('name', ''))) {
            $model = $model->whereLike('name', '%' . $name . '%');
        }

        return json([
            "count" => $model->count('id'),
            "data"  => $model->page($this->get('page', 1), $this->get('limit', 20))
                ->order('id', 'desc')
                ->select()->each(function ($query) {
                    $query->type_txt = $query->type_text;
                    $query->exp      = 0;
                    $query->gold     = 0;
                    $query->diamond  = 0;
                    foreach ($query->reward as $item) {
                        switch ($item->reward_type) {
                            case 0:
                                $query->exp = $item->quantity;
                                break;
                            case 1:
                                $query->gold = $item->quantity == 0 ? 0 : bcdiv($item->quantity, '100', 2);
                                break;
                            case 2:
                                $query->diamond = $item->quantity == 0 ? 0 : bcdiv($item->quantity, '100', 2);
                                break;
                        }
                    }
                })
                ->toArray(),
            "code"  => 0,
            "msg"   => "",
        ]);
    }

    /**
     * 添加页面
     * @return mixed
     */
    public function add()
    {
        $allow_add_list = TaskModel::TYPE_NAME_ALLOW_ADD;
        $gift_list      = GiftModel::where('status', 1)->where('type', 2)->field('id,title')->select();
        $props_new      = PropsNewModel::where('status', 1)->field('id,name')->select();
        $page_tag_cate  = TaskModel::PAGE_TAG_CATE;

        $this->assign("page_tag_cate", $page_tag_cate);
        $this->assign("props_new", $props_new);
        $this->assign("gift_list", $gift_list);
        $this->assign("allow_add_list", $allow_add_list);
        $this->assign("checkin_type", TaskModel::CHECK_IN_TYPE);
        $this->assign("type_cate", TaskModel::TYPE_CATE);
        return $this->fetch();
    }

    /**
     * 编辑页面
     * @return mixed
     */
    public function edit()
    {
        $id       = Request::get('id');
        $taskinfo = TaskModel::with('reward')->get($id);
        // 经验
        $taskinfo->exp = 0;
        // 鹰钻
        $taskinfo->gold = 0;
        // 克拉
        $taskinfo->diamond = 0;
        // 贵族体验天数
        $taskinfo->nobel_day = 0;
        // 抽奖次数
        $taskinfo->luck_draw = 0;
        // 礼物id
        $gift_reward = [];
        // 道具
        $props_reward = [];

        // 0=经验,1=鹰钻 2=克拉 3=礼物 4=贵族体验天数，5=道具，6=奖励抽奖次数
        foreach ($taskinfo->reward as $val) {
            switch ($val->reward_type) {
                case 0:
                    // 奖励经验
                    $taskinfo->exp = $val->quantity;
                    break;
                case 1:
                    // 奖励鹰钻
                    $taskinfo->gold = bcdiv($val->quantity, '100', 2);
                    break;
                case 2:
                    // 奖励克拉
                    $taskinfo->diamond = bcdiv($val->quantity, '100', 2);
                    break;
                case 3:
                    // 奖励礼物
                    $gift_reward = [
                        'id'  => $val->gift_id,
                        'num' => $val->quantity,
                    ];
                    break;
                case 4:
                    // 奖励贵族体验天数
                    $taskinfo->nobel_day = $val->quantity;
                    break;
                case 5:
                    // 奖励道具
                    $props_reward = [
                        'id'  => $val->props_id,
                        'num' => $val->quantity,
                    ];
                    break;
                case 6:
                    // 奖励抽奖次数
                    $taskinfo->luck_draw = $val->quantity;
                    break;
            }
        }

        unset($taskinfo->reward);

        $type_cate = TaskModel::TYPE_CATE;
        return $this->assign([
            'gift_list'      => GiftModel::where('status', 1)->where('type', 2)->field('id,title')->select(),
            'props_new'      => PropsNewModel::where('status', 1)->field('id,name')->select(),
            'type_cate_name' => isset($type_cate[$taskinfo->type]) ? $type_cate[$taskinfo->type] : '',
            'gift_reward'    => $gift_reward,
            'props_reward'   => $props_reward,
            'taskinfo'       => $taskinfo,
            'page_tag_cate'  => TaskModel::PAGE_TAG_CATE,
            'gift_info'      => json_decode($taskinfo->gift_info, true) ?? []
        ])->fetch();
    }

    /**
     * 添加操作逻辑
     * @return \think\response\Json
     */
    public function add_post()
    {
        $all_param = Request::param();

        $validate = new Validate([
            'name'        => 'require|max:50',
            'description' => 'require|max:200',
            'type'        => 'require|in:0,1,2,3',
            'weight'      => 'require|number',
        ], [
            "name"        => "请输入标题，标题最多50字",
            "description" => "请输入规则，规则最多200字",
            "type"        => "请正确选择任务类别",
            "weight"      => "请正确输入权重",
        ]);

        if (!$validate->check($all_param)) {
            return static::bulidFail($validate->getError());
        }

        if (empty($all_param['frequency']) || !is_numeric($all_param['frequency']) || $all_param['frequency'] <= 0) {
            return static::bulidFail('任务次数错误');
        }

        // 签到标题
        $check_type = TaskModel::CHECK_IN_TYPE;

        $task_model             = new TaskModel($all_param);
        $task_model->manager_id = $this->admin_id;
        $task_model->name       = str_replace('N', $task_model->frequency, $task_model->name);
        $task_model->page_tag   = $this->post('page_tag', 0);
        $task_model->gift_info  = '';

        if ($task_model->type == 3) {
            if (!isset($check_type[$task_model->name])) {
                return static::bulidFail('请正确选择连续签到标题');
            }
            $task_model->name = $check_type[$task_model->name];
        }

        // 查询任务标题是否存在
        if (TaskModel::where('name', $task_model->name)->find()) {
            return static::bulidFail($task_model->name . '任务已经存在，请不要重复添加');
        }

        Db::startTrans();
        try {
            if (!$task_model->save()) {
                return static::bulidFail('添加任务信息失败');
            }

            $reward_data = [];

            // 经验值
            if (!empty($all_param['exp']) && $all_param['exp'] > 0) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 0,
                    'gift_id'     => 0,
                    'quantity'    => $all_param['exp'],
                );
            }

            // 鹰钻数量
            if (is_numeric($gold = rtrim(trim($this->post('gold', '')), '.')) && bccomp($gold, '0', 2) == 1) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 1,
                    'gift_id'     => 0,
                    'quantity'    => bcmul($gold, '100', 0),
                );
            }

            // 克拉数量
            if (is_numeric($diamond = rtrim(trim($this->post('diamond', '')), '.')) && bccomp($diamond, '0', 2) == 1) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 2,
                    'gift_id'     => 0,
                    'quantity'    => bcmul($diamond, '100', 0),
                );
            }

            // 贵族体验天数
            if (is_numeric($nobel_day = rtrim(trim($this->post('nobel_day', '')), '.')) && $nobel_day > 0) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 4,
                    'gift_id'     => 0,
                    'quantity'    => $nobel_day,
                );
            }

            // 礼物
            if ($all_param['gift_id'] > 0 && $all_param['gift_num'] > 0) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 3,
                    'gift_id'     => $all_param['gift_id'],
                    'quantity'    => $all_param['gift_num'],
                );
            }

            // 道具
            if ($all_param['props_id'] > 0 && $all_param['props_num'] > 0) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 5,
                    'gift_id'     => 0,
                    'props_id'    => $all_param['props_id'],
                    'quantity'    => $all_param['props_num'],
                );
            }

            // 转盘抽奖次数
            if (is_numeric($luck_draw = rtrim(trim($this->post('luck_draw', '')), '.')) && $luck_draw > 0) {
                $reward_data[] = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 6,
                    'gift_id'     => 0,
                    'quantity'    => $luck_draw,
                );
            }

            if ($reward_data) {
                $task_reward_model = new TaskRewardModel();
                $task_reward_id    = $task_reward_model->isUpdate(false)->saveAll($reward_data);
                if (empty($task_reward_id)) {
                    throw new \Exception('添加任务信息失败');
                }
            }

            Db::commit();
            // 记录日志
            $log_content = "发布任务，ID：{$task_model->id}，标题：{$task_model->name}";
            parent::addAdminLog($log_content);
            return static::bulidSuccess([], '创建成功');
        } catch (\Exception $e) {
            Db::rollback();
            return self::bulidDataFail(['error' => $e->getMessage()], '添加任务信息失败');
        }

        return static::bulidFail();
    }

    /**
     * 编辑操作逻辑
     * @return \think\response\Json
     */
    public function edit_post()
    {
        if (!$task_model = TaskModel::where('id', $this->post('id'))->find()) {
            return static::bulidFail('任务信息不存在');
        }

        $validate = new Validate([
            'description' => 'require|max:200',
            'weight'      => 'require|number',
        ], [
            "description" => "请输入规则，规则最多200字",
            "weight"      => "请正确输入权重",
        ]);

        if (!$validate->check($this->post())) {
            return static::bulidFail($validate->getError());
        }

        if (!($frequency = $this->post('frequency')) || !is_numeric($frequency) || $frequency <= 0) {
            return static::bulidFail('条件次数错误');
        }

        $task_model->weight      = $this->post('weight', 0);
        $task_model->status      = $this->post('status', 0);
        $task_model->description = trim($this->post('description', ''));
        $task_model->manager_id  = $this->admin_id;
        $task_model->frequency   = $frequency;
        $task_model->page_tag    = $this->post('page_tag', 0);
        $task_model->gift_info   = '';

        // 查询任务标题是否存在
        $e_where = [
            ['id', '<>', $task_model->id],
            ['name', '=', $task_model->name],
        ];
        if (TaskModel::where($e_where)->find()) {
            return static::bulidFail($task_model->name . '任务已经存在，请不要重复设置');
        }

        Db::startTrans();
        try {

            if (!$task_model->save('修改任务信息失败')) {
                return static::bulidFail();
            }

            // 经验值
            if (is_numeric($exp = $this->post('exp')) && $exp > 0) {
                $reward_data = [
                    'task_id'     => $task_model->id,
                    'reward_type' => 0,
                    'gift_id'     => 0,
                    'quantity'    => $exp,
                ];

                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 0)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改经验值失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 0)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除经验值失败');
                }
            }

            // 克拉数量
            if (is_numeric($diamond = rtrim(trim($this->post('diamond', '')), '.')) && bccomp($diamond, '0', 2) >= 0) {
                $reward_data = [
                    'task_id'     => $task_model->id,
                    'gift_id'     => 0,
                    'reward_type' => 2,
                    'quantity'    => bcmul($diamond, '100', 2),
                ];

                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 2)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改克拉数量失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 2)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除克拉数量失败');
                }
            }

            // 鹰钻数量
            if (is_numeric($gold = rtrim(trim($this->post('gold', '')), '.')) && bccomp($gold, '0', 2) >= 0) {
                $reward_data = [
                    'task_id'     => $task_model->id,
                    'gift_id'     => 0,
                    'reward_type' => 1,
                    'quantity'    => bcmul($gold, '100', 0),
                ];

                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 1)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改钻石数量失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 1)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除钻石数量失败');
                }
            }

            // 贵族体验天数
            if (is_numeric($nobel_day = rtrim(trim($this->post('nobel_day', '')), '.')) && $nobel_day > 0) {
                $reward_data = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 4,
                    'gift_id'     => 0,
                    'quantity'    => $nobel_day,
                );
                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 4)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改贵族体验天数失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 4)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除贵族体验天数失败');
                }
            }

            // 礼物
            if ($this->post('gift_id', 0, 'intval') > 0 && $this->post('gift_num', 0, 'intval') > 0) {
                $reward_data = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 3,
                    'gift_id'     => $this->post('gift_id', 0, 'intval'),
                    'quantity'    => $this->post('gift_num', 0, 'intval'),
                );
                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 3)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改礼物失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 3)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除礼物失败');
                }
            }

            // 道具
            if ($this->post('props_id', 0, 'intval') > 0 && $this->post('props_num', 0, 'intval') > 0) {
                $reward_data = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 5,
                    'gift_id'     => 0,
                    'props_id'    => $this->post('props_id', 0, 'intval'),
                    'quantity'    => $this->post('props_num', 0, 'intval'),
                );
                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 5)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改道具失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 5)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除道具失败');
                }
            }

            // 转盘抽奖次数
            if (is_numeric($luck_draw = rtrim(trim($this->post('luck_draw', '')), '.')) && $luck_draw > 0) {
                $reward_data = array(
                    'task_id'     => $task_model->id,
                    'reward_type' => 6,
                    'gift_id'     => 0,
                    'quantity'    => $luck_draw,
                );

                // 如果存在则修改，不存在则添加
                if (!$tmpModel = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 6)->find()) {
                    $tmpModel = new TaskRewardModel();
                }

                if (!$tmpModel->save($reward_data)) {
                    throw new \Exception('修改转盘抽奖次数失败');
                }
            } else {
                $task_reward_model = TaskRewardModel::where('task_id', $task_model->id)->where('reward_type', 6)->find();
                if ($task_reward_model && !$task_reward_model->delete()) {
                    throw new \Exception('删除转盘抽奖次数失败');
                }
            }

            Db::commit();
            // 记录日志
            $log_content = "修改任务，ID：{$task_model->id}，标题：{$task_model->name}";
            parent::addAdminLog($log_content);
            return static::bulidSuccess([], '修改成功');
        } catch (\Exception $e) {
            Db::rollback();
            return self::bulidDataFail(['error' => $e->getMessage()], '修改失败');
        }
        return static::bulidFail('修改失败');
    }

    /**
     * 设置任务状态
     * @return \think\response\Json
     */
    public function set_status()
    {
        $status     = Request::param("status");
        $task_model = TaskModel::get(Request::param("id"));
        if (!$task_model) {
            return self::bulidFail("参数错误");
        }

        $task_model->status        = $status;
        $task_model->motified_time = nowFormat();

        if ($task_model->save()) {
            // 记录日志
            $log_content = ($status == 0 ? '启用' : '停用') . "任务信息，ID：{$task_model->id}，标题：{$task_model->name}";
            parent::addAdminLog($log_content);

            return self::bulidSuccess();
        }
        return self::bulidFail();
    }

    /**
     * 任务列表
     * @return mixed
     */
    public function user_receive()
    {
        $type_cate = TaskModel::TYPE_CATE;
        $this->assign("type_cate", $type_cate);
        return $this->fetch();
    }

    /**
     * 列表数据
     * @return \think\response\Json
     */
    public function user_receive_list()
    {
        $name        = Request::param("name");
        $is_received = Request::param("is_received");
        $uid         = Request::param("uid");
        $start_time  = Request::param("start_time");
        $end_time    = Request::param("end_time");
        $type        = Request::param("type");
        $page        = Request::param("page");
        $limit       = Request::param("limit");

        $where = [];
        if ($uid > 0) {
            $where[] = ['uid', '=', $uid];
        }
        if ($start_time) {
            $where[] = ["create_time", ">=", $start_time];
        }
        if ($end_time) {
            $where[] = ["create_time", "<", $end_time];
        }
        if (is_numeric($is_received)) {
            $where[] = ['is_received', '=', $is_received];
        }

        // 查询任务分类及标题
        $t_where = [];
        if (is_numeric($type)) {
            $t_where[] = ['type', '=', $type];
        }
        if ($name) {
            $t_where[] = ['name', 'like', "%$name%"];
        }

        if ($t_where) {
            $task_list     = TaskModel::where($t_where)->column('id');
            $task_list_ids = array_unique(array_filter($task_list));
            if ($task_list_ids) {
                $where[] = ["task_id", "in", $task_list_ids];
            } else {
                $where[] = ["task_id", "=", 0];
            }
        }

        $list = UserTaskModel::with([
            'user',
            'task' => function ($query) {
                $query->field('id,name,type,status,frequency');
            }])->where($where)
            ->limit(($page - 1) * $limit, $limit)
            ->order('id DESC')
            ->select();
        if (count($list) > 0) {
            $count = UserTaskModel::where($where)->count();

            // 获取奖励配置记录
            $list_array      = $list->toArray();
            $task_reward_ids = array_column($list_array, 'task_id');
            $task_reward_ids = array_filter(array_unique($task_reward_ids));
            $task_reward     = TaskRewardModel::whereIn('task_id', $task_reward_ids)->select();

            // 礼物数组
            $gift_list = GiftModel::where('status', 1)->field('id,title')->select()->toArray();
            $gift_list = array_column($gift_list, 'title', 'id');

            foreach ($list as &$item) {
                $item->exp            = 0;
                $item->diamond        = 0;
                $item->gold           = 0;
                $item->gift_id        = 0;
                $item->task->type_txt = $item->task->type_text;

                // 礼物
                $gift_title = array();

                foreach ($task_reward as $val) {
                    if ($val->task_id != $item->task_id) {
                        continue;
                    }

                    switch ($val->reward_type) {
                        case 0:
                            $item->exp = $val->quantity;
                            break;
                        case 1:
                            $item->gold = bcdiv(strval($val->quantity), '100', 2);
                            break;
                        case 2:
                            $item->diamond = bcdiv(strval($val->quantity), '100', 2);
                            break;
                        case 3:
                            $gift_title[] = isset($gift_list[$val->gift_id]) ? $gift_list[$val->gift_id] : '';
                            break;
                    }
                }
                $gift_title       = array_unique(array_filter($gift_title));
                $item->gift_title = implode(',', $gift_title);
            }

            return json(["code" => 0, "msg" => "", "data" => $list, "count" => $count]);
        }
        return self::bulidFail("未查询到相关数据");
    }

    public function del()
    {
        if (!($id = $this->post('id')) || !is_numeric($id)) {
            return static::bulidFail();
        }

        if (!$model = TaskModel::field('id')->where('id', $id)->find()) {
            return static::bulidFail('不存在的任务!');
        }

        if (!$model->delete()) {
            return static::bulidFail();
        }

        return static::bulidSuccess();
    }
}